home *** CD-ROM | disk | FTP | other *** search
- /* New BDS library for use with software tools
- * source: toolib1.bds
- * version: November 26, 1981
- */
-
- #include tools.h
-
- /*
- This file contains all the standard BDS C library functions
- which are written in C that are used by the software tools
- programs.
-
- These library functions are identical to the functions
- which were on files stdlib1 and stdlib2.c
- EXCEPT that these functions call some routines whose names
- have changed.
-
- The object code for these functions used to be on deff.crl.
- Now the object code is on toolib1.crl.
-
- The functions on this file ONLY use functions on toolib2.crl
- All the functions with new names are on file toolib2.crl.
- All functions on toolib2.crl came from deff2.crl.
-
- The names have all been changed in the same way,
- viz., by adding a leading underscore character to the
- name. The following functions have been renamed:
-
- ( * denotes that a call to the function is in this file)
-
- _getchar _ungetch _putchar * _putch
- _gets * _call _read * _write
- _open * _close * _creat (_unlink)
- _seek (_tell) _rename _exit
- _rread _rwrite _rseek _rtell
- _rsrec _rcfsiz
-
-
- The following functions were on stdlib1.c but
- have been deleted from this file.
-
- getc(), putc(), and ungetc() are now defined on file.bds.
- They had to be completely rewritten to allow for I/O
- redirection.
-
- fopen getc ungetc getw
- fcreat putc putw
- fflush fclose
-
- strcat strcmp strcpy strlen
- qsort
- initw initb getval
-
- The following functions from stdlib1.c are on this file:
-
- qsort
- atoi
- isalpha isupper islower isdigit
- isspace toupper tolower
- alloc free
- abs max min
-
- */
-
- /*
- This is the new qsort routine, utilizing the shell sort
- technique given in the Software Tools book (by Kernighan
- & Plauger.)
-
- NOTE: this "qsort" function is different from the "qsort" given
- in some old releases (pre 1.32) -- here, the items are sorted
- in ASCENDING order.
- */
-
- qsort(base, nel, width, compar)
- char *base; int (*compar)();
- { int gap,ngap, i, j;
- int jd, t1, t2;
- t1 = nel * width;
- for (ngap = nel / 2; ngap > 0; ngap /= 2) {
- gap = ngap * width;
- t2 = gap + width;
- jd = base + gap;
- for (i = t2; i <= t1; i += width)
- for (j = i - t2; j >= 0; j -= gap) {
- if ((*compar)(base+j, jd+j) <=0) break;
- _swp(width, base+j, jd+j);
- }
- }
- }
-
- _swp(w,a,b)
- char *a,*b;
- int w;
- {
- char tmp;
- while(w--) {tmp=*a; *a++=*b; *b++=tmp;}
- }
-
-
- /*
- Some string functions
- */
-
- int atoi(n)
- char *n;
- {
- int val;
- char c;
- int sign;
- val=0;
- sign=1;
- while ((c = *n) == '\t' || c== ' ') ++n;
- if (c== '-') {sign = -1; n++;}
- while ( isdigit(c = *n++)) val = val * 10 + c - '0';
- return sign*val;
- }
-
-
- /*
- Some character diddling functions
- */
-
- int isalpha(c)
- char c;
- {
- return isupper(c) || islower(c);
- }
-
-
- int isupper(c)
- char c;
- {
- return c>='A' && c<='Z';
- }
-
-
- int islower(c)
- char c;
- {
- return c>='a' && c<='z';
- }
-
-
- int isdigit(c)
- char c;
- {
- return c>='0' && c<='9';
- }
-
-
- int isspace(c)
- char c;
- {
- return c==' ' || c=='\t' || c=='\n';
- }
-
-
- char toupper(c)
- char c;
- {
- return islower(c) ? c-32 : c;
- }
-
-
- char tolower(c)
- char c;
- {
- return isupper(c) ? c+32 : c;
- }
-
-
- /*
- Storage allocation routines, taken from chapter 8 of K&R, but
- simplified to ignore the storage allignment problem and not
- bother with the "morecore" hack (a call to "sbrk" under CP/M is
- a relatively CHEAP operation, and can be done on every call to
- "alloc" without degrading efficiency.)
- */
-
- char *alloc(nbytes)
- unsigned nbytes;
- {
- struct _header *p, *q, *cp;
- int nunits;
-
- /* comment out -----
- printf("In alloc: nbytes = %d\n", nbytes);
- ----- end comment out */
-
- nunits = 1 + (nbytes + (sizeof (_base) - 1)) / sizeof (_base);
- if ((q = _allocp) == NULL) {
- _base._ptr = _allocp = q = &_base;
- _base._size = 0;
- }
- for (p = q -> _ptr; ; q = p, p = p -> _ptr) {
- if (p -> _size >= nunits) {
- if (p -> _size == nunits)
- q -> _ptr = p -> _ptr;
- else {
- p -> _size -= nunits;
- p += p -> _size;
- p -> _size = nunits;
- }
- _allocp = q;
-
- /* comment out -----
- printf("Alloc returns: %x\n", p+1);
- ----- end comment out */
-
- return p + 1;
- }
- if (p == _allocp) {
- cp = sbrk(nunits * sizeof (_base));
- if (cp == ERROR) {
- printf("Alloc: Out of memory");
- return NULL;
- }
- cp -> _size = nunits;
- /* remember: pointer arithmetic ! */
- free(cp+1);
- p = _allocp;
- }
- }
- }
-
-
- free(ap)
- struct _header *ap;
- {
- struct _header *p, *q;
-
- /* comment out -----
- printf("In free: ap = %x\n", ap);
- ----- end comment out */
-
- p = ap - 1; /* No need for the cast when "ap" is a struct ptr */
-
- for (q = _allocp; !(p > q && p < q -> _ptr); q = q -> _ptr)
- if (q >= q -> _ptr && (p > q || p < q -> _ptr))
- break;
- if (p + p -> _size == q -> _ptr) {
- p -> _size += q -> _ptr -> _size;
- p -> _ptr = q -> _ptr -> _ptr;
- }
- else p -> _ptr = q -> _ptr;
-
- if (q + q -> _size == p) {
- q -> _size += p -> _size;
- q -> _ptr = p -> _ptr;
- }
- else q -> _ptr = p;
-
- _allocp = q;
-
- /* comment out -----
- printf("In free: new _allocp = %x\n", q);
- ----- end comment out */
-
- }
-
-
- /*
- define max(), min(), abs()
- */
-
- int abs(n)
- {
- return (n<0) ? -n : n;
- }
-
- int max(a,b)
- {
- return (a > b) ? a : b;
- }
-
- int min(a,b)
- {
- return (a <= b) ? a : b;
- }
-
-
-
- /*
- The following functions from stdlib2.c are on this file:
-
- printf _spr
- scanf _scn
- _puts (renamed by analogy to _get)
- swapin
-
- The following functions from stdlib2 have been deleted:
-
- fprintf sprintf
- scanf sscanf
- fputs fgets
-
-
- Many comments have been deleted from these functions.
- See STDLIB2.C if you are really interested.
-
- Each function uses an array of dimension MAXLINE.
- Make sure MAXLINE is longer than the largest line
- ever printed!
-
- Remember to put out a 0x1a (control-Z, CPMEOF) at
- the end of text files being written out to disk.
-
- Also remember that there are two end of file
- conditions: -1 and CPMEOF.
- */
-
-
- /*
- printf
-
- usage:
- printf(format, arg1, arg2, ...);
-
- Exactly the same as in Kernighan & Ritchie.
- */
-
- printf(format)
- char *format;
- {
- char line[MAXLINE];
-
- _spr(line,&format); /* use "_spr" to form the output */
-
- /* comment out -----
- _puts(line); /* and print out the line */
- ----- end comment out */
- putlin(line, STDOUT);
- }
-
-
- /*
- scanf:
- This one accepts a line of input text from the
- console, and converts the text to the required
- binary or alphanumeric form. (see K & R)
-
- Usage:
- scanf(format, ptr1, ptr2, ...);
-
- Returns number of items matched.
-
- Since a new line of text must be entered from the
- console each time scanf is called, any unprocessed
- text left over from the last call is lost forever.
- This is a difference between BDS and UNIX.
-
- The field width specification is not supported.
- */
-
- int scanf(format)
- char *format;
- {
- char line[MAXLINE];
-
- /* comment out -----
- _gets(line); /* get a line of input from user */
- ----- end comment out */
- getlin(line, STDIN);
-
- return _scn(line,&format); /* and scan it with "_scn" */
- }
-
-
- /*
- sprintf:
- Like fprintf, except a string pointer is specified
- instead of a buffer pointer. The text is written
- directly into memory where the string pointer points.
-
- Usage:
- sprintf(string,format,arg1, arg2, ...);
- */
-
- sprintf(buffer,format)
- char *buffer, *format;
- {
- _spr(buffer,&format); /* call _spr to do all the work */
- }
-
-
- /*
- sscanf:
-
- Reads a line of text in from the console and scans it
- for variable values specified in the format string.
- See the comments below in _scn()
-
- Usage:
- sscanf(format,&arg1,&arg2,...);
- */
-
- int sscanf(line,format)
- char *line, *format;
- {
- return _scn(line,&format); /* let _scn do all the work */
- }
-
-
-
- /*
- General formatted output conversion routine, used by
- fprintf and sprintf..."line" is where the output is
- written, and "fmt" is a pointer to an argument list
- which must consist of a format string pointer and
- subsequent list of (optional) values.
-
- The arguments are, of course, passed on the stack.
- */
-
-
- _spr(line,fmt)
- char *line, **fmt;
- {
- char _uspr(), c, base, *sptr, *format;
- char wbuf[MAXLINE], *wptr, pf, ljflag, zfflag;
- int width, precision, *args;
-
- format = *fmt++; /* fmt first points to the format string */
- args = fmt; /* now fmt points to the first arg value */
-
- while (c = *format++)
- if (c == '%') {
- wptr = wbuf;
- precision = 6;
- ljflag = pf = zfflag = 0;
-
- if (*format == '-') {
- format++;
- ljflag++;
- }
-
-
- if (*format == '0') zfflag++; /* zero-fill feature test */
-
- width = (isdigit(*format)) ? _gv2(&format) : 1;
-
- if ((c = *format++) == '.') {
- precision = _gv2(&format);
- pf++;
- c = *format++;
- }
-
- switch(toupper(c)) {
-
- case 'D': if (*args < 0) {
- *wptr++ = '-';
- *args = -*args;
- width--;
- }
-
- case 'U': base = 10; goto val;
-
- case 'X': base = 16; goto val;
-
- case 'O': base = 8; /* note that arbitrary bases can be
- added easily before this line */
-
- val: width -= _uspr(&wptr,*args++,base);
- goto pad;
-
- case 'C': *wptr++ = *args++;
- width--;
- goto pad;
-
- case 'S': if (!pf) precision = 200;
- sptr = *args++;
- while (*sptr && precision) {
- *wptr++ = *sptr++;
- precision--;
- width--;
- }
-
- pad: *wptr = '\0';
- pad2: wptr = wbuf;
- if (!ljflag)
- while (width-- > 0)
- *line++ = zfflag ? '0' : ' ';
-
- while (*line = *wptr++)
- line++;
-
- if (ljflag)
- while (width-- > 0)
- *line++ = ' ';
- break;
-
- default: *line++ = c;
-
- }
- }
- else *line++ = c;
-
- *line = '\0';
- }
-
- /*
- Internal routine used by "_spr" to perform ascii-
- to-decimal conversion and update an associated pointer:
- */
-
- int _gv2(sptr)
- char **sptr;
- {
- int n;
- n = 0;
- while (isdigit(**sptr)) n = 10 * n + *(*sptr)++ - '0';
- return n;
- }
-
-
- /*
- Internal function which converts n into an ASCII
- base `base' representation and places the text
- at the location pointed to by the pointer pointed
- to by `string'. Yes, you read that correctly.
- */
-
- char _uspr(string, n, base)
- char **string;
- unsigned n;
- {
- char length;
- if (n<base) {
- *(*string)++ = (n < 10) ? n + '0' : n + 55;
- return 1;
- }
- length = _uspr(string, n/base, base);
- _uspr(string, n%base, base);
- return length + 1;
- }
-
-
- /*
- General formatted input conversion routine. "line" points
- to a string containing ascii text to be converted, and "fmt"
- points to an argument list consisting of first a format
- string and then a list of pointers to the destination objects.
-
- Appropriate data is picked up from the text string and stored
- where the pointer arguments point according to the format string.
- See K&R for more info.
-
- The field width specification is not supported.
-
- NOTE: the "%s" termination character has been changed
- from "any white space" to the character following the
- the %s specification in the format string.
- That is, the call
-
- sscanf(string, "%s:", &str);
-
- would ignore leading white space (as is the case with
- all format conversions), and then read in ALL following
- text (including newlines) into the buffer "str"
- until a COLON or null byte is encountered.
-
- */
-
- int _scn(line,fmt)
- char *line, **fmt;
- {
- char sf, c, base, n, *sptr, *format;
- int sign, val, **args;
-
- format = *fmt++; /* fmt first points to the format string */
- args = fmt; /* now it points to the arg list */
-
- n = 0;
- while (c = *format++) {
- if (!*line) return n; /* if end of input string, return */
- if (isspace(c)) continue; /* skip white space in format string */
- if (c != '%') { /* if not %, must match text */
- if (c != _igs(&line)) return n;
- else line++;
- }
- else { /* process conversion */
- sign = 1;
- base = 10;
- sf = 0;
- if ((c = *format++) == '*') {
- sf++; /* if "*" given, supress assignment */
- c = *format++;
- }
- switch (toupper(c)) {
- case 'X': base = 16;
- goto doval;
-
- case 'O': base = 8;
- goto doval;
-
- case 'D': if (_igs(&line) == '-') {
- sign = -1;
- line++;
- }
-
- doval: case 'U': val = 0;
- if (_bc(_igs(&line),base) == ERROR)
- return n;
- while ((c = _bc(*line++,base)) != 255)
- val = val * base + c;
- line--;
- break;
-
- case 'S': _igs(&line);
- sptr = *args;
- while (c = *line++) {
- if (c == *format) {
- format++;
- break;
- }
- if (!sf) *sptr++ = c;
- }
- if (!sf) {
- n++;
- *sptr = '\0';
- args++;
- }
- continue;
-
- case 'C': if (!sf) {
- poke(*args++, *line);
- n++;
- }
- line++;
- continue;
-
- default: return n;
- }
- if (!sf) {
- **args++ = val * sign;
- n++;
- }
- }}
- return n;
- }
-
- /*
- Internal function to position the character
- pointer argument to the next non white-space
- character in the string:
- */
-
- char _igs(sptr)
- char **sptr;
- {
- char c;
- while (isspace(c = **sptr)) ++*sptr;
- return (c);
- }
-
-
- /*
- Internal function to convert character c to value
- in base b , or return ERROR if illegal character for that
- base:
- */
-
- int _bc(c,b)
- char c,b;
- {
- if (isalpha(c = toupper(c))) c -= 55;
- else if (isdigit(c)) c -= 0x30;
- else return ERROR;
- if (c > b-1) return ERROR;
- else return c;
- }
-
-
- /*
- _puts:
- Write out the given string to the console.
- A newline is NOT automatically appended:
- */
-
- _puts(s)
- char *s;
- {
- while (*s) _putchar(*s++);
- }
-
-
- swapin(name,addr)
- char *name; /* the file to swap in */
- {
- int fd;
- if (( fd = _open(name,0)) == ERROR) {
- printf("Swapin: cannot open %s\n",name);
- return ERROR;
- }
- if ((_read(fd,addr,512)) < 0) {
- printf("Swapin: read error on %s\n",name);
- _close(fd);
- return ERROR;
- }
- _close(fd);
- return OK;
- }
-
-